import { ref, computed, ComputedRef, unref } from 'vue';
import { useEventListener } from '@/hooks/event/useEventListener';
import { screenMap, sizeEnum, screenEnum } from '@/enums/breakpointEnum';

let globalScreenRef: ComputedRef<sizeEnum | undefined>;
let globalWidthRef: ComputedRef<number>;
let globalRealWidthRef: ComputedRef<number>;

export interface CreateCallbackParams {
    screen: ComputedRef<sizeEnum | undefined>;
    width: ComputedRef<number>;
    realWidth: ComputedRef<number>;
    screenEnum: typeof screenEnum;
    screenMap: Map<sizeEnum, number>;
    sizeEnum: typeof sizeEnum;
}

export function useBreakpoint() {
    return {
        screenRef: computed(() => unref(globalScreenRef)),
        widthRef: globalWidthRef,
        screenEnum,
        realWidthRef: globalRealWidthRef,
    };
}

// Just call it once
export function createBreakpointListen(fn?: (opt: CreateCallbackParams) => void) {
    const screenRef = ref<sizeEnum>(sizeEnum.XL);
    const realWidthRef = ref(window.innerWidth);

    function getWindowWidth() {
        const width = document.body.clientWidth;
        const xs = screenMap.get(sizeEnum.XS)!;
        const sm = screenMap.get(sizeEnum.SM)!;
        const md = screenMap.get(sizeEnum.MD)!;
        const lg = screenMap.get(sizeEnum.LG)!;
        const xl = screenMap.get(sizeEnum.XL)!;
        if (width < xs) {
            screenRef.value = sizeEnum.XS;
        } else if (width < sm) {
            screenRef.value = sizeEnum.SM;
        } else if (width < md) {
            screenRef.value = sizeEnum.MD;
        } else if (width < lg) {
            screenRef.value = sizeEnum.LG;
        } else if (width < xl) {
            screenRef.value = sizeEnum.XL;
        } else {
            screenRef.value = sizeEnum.XXL;
        }
        realWidthRef.value = width;
    }

    useEventListener({
        el: window,
        name: 'resize',

        listener: () => {
            getWindowWidth();
            resizeFn();
        },
        // wait: 100,
    });

    getWindowWidth();
    globalScreenRef = computed(() => unref(screenRef));
    globalWidthRef = computed((): number => screenMap.get(unref(screenRef)!)!);
    globalRealWidthRef = computed((): number => unref(realWidthRef));

    function resizeFn() {
        fn?.({
            screen: globalScreenRef,
            width: globalWidthRef,
            realWidth: globalRealWidthRef,
            screenEnum,
            screenMap,
            sizeEnum,
        });
    }

    resizeFn();
    return {
        screenRef: globalScreenRef,
        screenEnum,
        widthRef: globalWidthRef,
        realWidthRef: globalRealWidthRef,
    };
}
